#include <iostream>
#include <fstream>
#include <vector>

template<typename T>
T *load_vecs(const char *filename, int &n_data, int &dim) {
    std::ifstream in(filename, std::ios::binary);
    if (!in.is_open()) {
        std::cerr << "Open file error" << std::endl;
        exit(-1);
    }

    in.read((char *) &dim, 4);

    in.seekg(0, std::ios::end);
    std::ios::pos_type ss = in.tellg();
    size_t fsize = (size_t) ss;
    n_data = (int) (fsize / (sizeof(T) / 4 * dim + 1) / 4);

    T *data = new T[(size_t) n_data * (size_t) dim];

    in.seekg(0, std::ios::beg);
    for (int i = 0; i < n_data; i++) {
        in.seekg(4, std::ios::cur);
        in.read((char *) (data + i * dim), dim * sizeof(T));
    }
    in.close();

    return data;
}


template<typename T>
std::vector<T *>
read_data(const char *dataset_name, int &n_query, int &top_k, int &n_base, int &data_dim) {
    char path[256];
    std::printf("load ground truth\n");
    std::sprintf(path, "../data/%s/gnd-%d.ivecs", dataset_name, top_k);
    int *gnd = load_vecs<int>(path, n_query, top_k);
//    std::printf("%d %d %d %d %d %d\n", gnd[0], gnd[1], gnd[2], gnd[3], gnd[4], gnd[10]);

    std::printf("load query\n");
    sprintf(path, "../data/%s/query.fvecs", dataset_name);
    T *query = load_vecs<T>(path, n_query, data_dim);
//    std::printf("%d %d %d %d %d\n", query[0], query[1], query[2], query[3], query[4]);

    std::printf("load base\n");
    sprintf(path, "../data/%s/base.fvecs", dataset_name);
    T *base = load_vecs<T>(path, n_base, data_dim);
//    std::printf("%d %d %d %d %d\n", base[0], base[1], base[2], base[3], base[4]);
    std::vector<T *> res(3);
    res[0] = base;
    res[1] = query;
    res[2] = (T *) gnd;
    return res;
}

using namespace std;

int main(int argc, char **argv) {
    char *base_filename = "/home/bianzheng/Reverse-kRanks/tmp.dvecs";
    int n_data, n_dim;
    double *data = load_vecs<double>(base_filename, n_data, n_dim);
    printf("data %.3f %.3f %.3f %.3f %.3f %.3f, n_data %d, n_dim %d\n", data[0], data[1], data[2], data[3], data[4], data[5], n_data, n_dim);

}
